package com.example.thread.d5线程池处理Runnable和Callable任务;

import java.util.concurrent.*;

public class ThreadPoolTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 通过ThreadPoolExecutor创建一个线程池对象
//        public ThreadPoolExecutor(int corePoolSize,
//         int maximumPoolSize,
//         long keepAliveTime,
//         TimeUnit unit,
//         BlockingQueue<Runnable> workQueue,{new ArrayBlockingQueue<>(4),new LinkedBlockingQueue<>()}
//         ThreadFactory threadFactory,
//         RejectedExecutionHandler handler)

        // ExecutorService的常用方法
        /**
         * void execute(Runnable command) : 执行Runnable任务
         * Future<T> submit(Callable<T> task) : 执行Callable任务，返回未来任务对象，用于获取线程返回的结果
         * void shutdown（）: 等全部任务执行完毕后，在关闭线程池
         * List<Runnable> shutdownNow() : 立刻关闭线程池，停止正在执行的任务，并返回队列中未执行的任务
         */
        ExecutorService pool = new ThreadPoolExecutor(
                3,
                5,
                8,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(4),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());   // 常用 AbortPolicy:丢弃任务并抛出异常，默认策略 ，CallerRunsPolicy:由主线程负责执行任务
        // 1、使用线程池处理Runnable任务
        // 当核心线程在忙，任务队列已满，在有新的任务来时，就会创建临时线程
        Runnable target = new MyRunnable();
        pool.execute(target); // 线程池自动创建一个新线程，自动处理这个任务，自动执行的
        pool.execute(target); // 线程池自动创建一个新线程，自动处理这个任务，自动执行的
        pool.execute(target); // 线程池自动创建一个新线程，自动处理这个任务，自动执行的
        pool.execute(target); // 复用前面的核心线程
        pool.execute(target); // 复用前面的核心线程

//        pool.shutdown(); // 等待线程池的任务全部执行完毕后，再关闭线程池
//        pool.shutdownNow(); // 立即关闭线程池，不管任务是否执行完毕
        System.out.println("=============================");
        // 2、使用线程池处理Callable任务
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));
        Future<String> f4 = pool.submit(new MyCallable(400));

        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
    }
}
